package com.bridge.service.impl;

import com.bridge.mapper.SysDictConfigMapper;
import com.bridge.model.SysDictConfig;
import com.bridge.service.IRedisHashService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;


/**
 * @author bridge
 * @Date 2022/05/25/20:24
 */
@Service
public class RedisHashServiceImpl implements IRedisHashService {
    private static final Logger log = LoggerFactory.getLogger(RedisHashServiceImpl.class);

    private static final String RedisHashKey = "Redis:Hash";

    @Resource
    private SysDictConfigMapper sysDictConfigMapper;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;


    /**
     * 添加数据字典及其对应的选项(code-value)
     *
     * @param config
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer addSysDictConfig(SysDictConfig config) throws Exception {
        int res = sysDictConfigMapper.insertSelective(config);
        if (res > 0) {
            //实时触发数据字典的hash存储
            cacheConfigMap();
        }
        return config.getId();
    }


    /**
     * 取出缓存中所有的数据字典列表
     */
    @Override
    public Map<String, List<SysDictConfig>> getSysDictConfig() throws Exception {
        return getAllCacheConfig();
    }


    /**
     * 取出缓存中特定的数据字典列表
     *
     * @param type
     * @return
     * @throws Exception
     */
    @Override
    public List<SysDictConfig> getByType(final String type) throws Exception {
        return getCacheConfigByType(type);
    }


    /**
     * 实时获取所有有效的数据字典列表-转化为map-存入hash缓存中
     */
    @Async
    public void cacheConfigMap() {
        try {
            List<SysDictConfig> sysDictConfigList = sysDictConfigMapper.selectActiveConfigs();
            if (sysDictConfigList != null && !sysDictConfigList.isEmpty()) {
                Map<String, List<SysDictConfig>> dataMap = Maps.newHashMap();
                //所有的数据字典列表遍历 -> 转化为 hash存储的map
                sysDictConfigList.forEach(sysDictConfig -> {
                    List<SysDictConfig> list = dataMap.get(sysDictConfig.getType());
                    if (CollectionUtils.isEmpty(list)) {
                        list = Lists.newLinkedList();
                    }
                    list.add(sysDictConfig);
                    dataMap.put(sysDictConfig.getType(), list);
                });

                //存储到缓存hash中
                HashOperations<String, String, List<SysDictConfig>> hashOperations = redisTemplate.opsForHash();
                hashOperations.putAll(RedisHashKey, dataMap);
            }
        } catch (Exception e) {
            log.error("实时获取所有有效的数据字典列表-转化为map-存入hash缓存中-发生异常：", e.fillInStackTrace());
        }
    }

    /**
     * 实时获取所有有效的数据字典列表-转化为map-存入hash缓存中
     */
    @Async
    public void cacheConfigMap(String type) {
        try {
            List<SysDictConfig> sysDictConfigList = sysDictConfigMapper.selectListByType(type);
            if (CollectionUtils.isEmpty(sysDictConfigList)) {
                return;
            }
            Map<String, List<SysDictConfig>> dataMap = Maps.newHashMap();
            dataMap.put(type, sysDictConfigList);
            //存储到缓存hash中
            HashOperations<String, String, List<SysDictConfig>> hashOperations = redisTemplate.opsForHash();
            hashOperations.putAll(RedisHashKey, dataMap);
        } catch (Exception e) {
            log.error("实时获取所有有效的数据字典列表-转化为map-存入hash缓存中-发生异常：", e.fillInStackTrace());
        }
    }


    /**
     * 从缓存hash中获取所有的数据字典配置map
     *
     * @return 数据字典配置map
     */
    @Override
    public Map<String, List<SysDictConfig>> getAllCacheConfig() {
        Map<String, List<SysDictConfig>> map = Maps.newHashMap();
        try {
            HashOperations<String, String, List<SysDictConfig>> hashOperations = redisTemplate.opsForHash();
            map = hashOperations.entries(RedisHashKey);
        } catch (Exception e) {
            log.error("从缓存hash中获取所有的数据字典配置map-发生异常：", e.fillInStackTrace());
        }
        return map;
    }


    /**
     * 从缓存hash中获取特定的数据字典列表
     *
     * @param type type
     * @return
     */
    @Override
    public List<SysDictConfig> getCacheConfigByType(final String type) {
        List<SysDictConfig> list = Lists.newArrayList();
        try {
            HashOperations<String, String, List<SysDictConfig>> hashOperations = redisTemplate.opsForHash();
            list = hashOperations.get(RedisHashKey, type);
        } catch (Exception e) {
            log.error("从缓存hash中获取特定的数据字典列表-发生异常：", e.fillInStackTrace());
        }
        // 缓存数据
        if (CollectionUtils.isEmpty(list)) {
            cacheConfigMap();
        }
        return list;
    }

    @Override
    public List<SysDictConfig> update(String type) {
        cacheConfigMap(type);
        return getCacheConfigByType(type);
    }


}

